using System;
using System.Collections.Generic;
using Volo.Abp.Domain.Events;
using Volo.Abp.Domain.Entities.Events;

namespace MatrixFramework.Shared.Domain.Events
{
    /// <summary>
    /// 权限变更事件基类
    /// </summary>
    public abstract class PermissionChangedEvent : IDistributedEvent
    {
        /// <summary>
        /// 租户ID
        /// </summary>
        public Guid? TenantId { get; set; }

        /// <summary>
        /// 事件ID
        /// </summary>
        public Guid EventId { get; set; } = Guid.NewGuid();

        /// <summary>
        /// 事件时间
        /// </summary>
        public DateTime EventTime { get; set; } = DateTime.UtcNow;

        /// <summary>
        /// 操作者ID
        /// </summary>
        public Guid? OperatorId { get; set; }

        /// <summary>
        /// 操作者名称
        /// </summary>
        public string OperatorName { get; set; }

        /// <summary>
        /// 操作类型
        /// </summary>
        public PermissionOperationType OperationType { get; set; }

        /// <summary>
        /// 权限变更上下文
        /// </summary>
        public PermissionChangeContext Context { get; set; } = new PermissionChangeContext();

        /// <summary>
        /// 事件数据
        /// </summary>
        public Dictionary<string, object> Data { get; set; } = new();
    }

    /// <summary>
    /// 用户权限变更事件
    /// </summary>
    public class UserPermissionChangedEvent : PermissionChangedEvent
    {
        /// <summary>
        /// 用户ID
        /// </summary>
        public Guid UserId { get; set; }

        /// <summary>
        /// 用户名
        /// </summary>
        public string Username { get; set; }

        /// <summary>
        /// 变更的权限列表
        /// </summary>
        public List<PermissionChangeItem> ChangedPermissions { get; set; } = new();

        /// <summary>
        /// 用户当前所有权限
        /// </summary>
        public List<string> CurrentPermissions { get; set; } = new();

        /// <summary>
        /// 影响的角色列表
        /// </summary>
        public List<Guid> AffectedRoleIds { get; set; } = new();

        public UserPermissionChangedEvent()
        {
        }

        public UserPermissionChangedEvent(
            Guid userId,
            string username,
            PermissionOperationType operationType,
            List<PermissionChangeItem> changedPermissions = null)
        {
            UserId = userId;
            Username = username;
            OperationType = operationType;
            ChangedPermissions = changedPermissions ?? new List<PermissionChangeItem>();
        }
    }

    /// <summary>
    /// 角色权限变更事件
    /// </summary>
    public class RolePermissionChangedEvent : PermissionChangedEvent
    {
        /// <summary>
        /// 角色ID
        /// </summary>
        public Guid RoleId { get; set; }

        /// <summary>
        /// 角色名称
        /// </summary>
        public string RoleName { get; set; }

        /// <summary>
        /// 角色代码
        /// </summary>
        public string RoleCode { get; set; }

        /// <summary>
        /// 变更的权限列表
        /// </summary>
        public List<PermissionChangeItem> ChangedPermissions { get; set; } = new();

        /// <summary>
        /// 角色当前所有权限
        /// </summary>
        public List<string> CurrentPermissions { get; set; } = new();

        /// <summary>
        /// 影响的用户列表
        /// </summary>
        public List<Guid> AffectedUserIds { get; set; } = new();

        public RolePermissionChangedEvent()
        {
        }

        public RolePermissionChangedEvent(
            Guid roleId,
            string roleName,
            string roleCode,
            PermissionOperationType operationType,
            List<PermissionChangeItem> changedPermissions = null)
        {
            RoleId = roleId;
            RoleName = roleName;
            RoleCode = roleCode;
            OperationType = operationType;
            ChangedPermissions = changedPermissions ?? new List<PermissionChangeItem>();
        }
    }

    /// <summary>
    /// 权限定义变更事件
    /// </summary>
    public class PermissionDefinitionChangedEvent : PermissionChangedEvent
    {
        /// <summary>
        /// 权限名称
        /// </summary>
        public string PermissionName { get; set; }

        /// <summary>
        /// 权限显示名称
        /// </summary>
        public string DisplayName { get; set; }

        /// <summary>
        /// 权限模块
        /// </summary>
        public string Module { get; set; }

        /// <summary>
        /// 旧的权限信息
        /// </summary>
        public PermissionDefinition OldDefinition { get; set; }

        /// <summary>
        /// 新的权限信息
        /// </summary>
        public PermissionDefinition NewDefinition { get; set; }

        public PermissionDefinitionChangedEvent()
        {
        }

        public PermissionDefinitionChangedEvent(
            string permissionName,
            string module,
            PermissionOperationType operationType,
            PermissionDefinition oldDefinition = null,
            PermissionDefinition newDefinition = null)
        {
            PermissionName = permissionName;
            Module = module;
            OperationType = operationType;
            OldDefinition = oldDefinition;
            NewDefinition = newDefinition;
        }
    }

    /// <summary>
    /// Scope同步状态变更事件
    /// </summary>
    public class ScopeSyncStatusChangedEvent : PermissionChangedEvent
    {
        /// <summary>
        /// 同步目标类型
        /// </summary>
        public ScopeSyncTargetType TargetType { get; set; }

        /// <summary>
        /// 目标ID（用户ID或角色ID）
        /// </summary>
        public Guid TargetId { get; set; }

        /// <summary>
        /// 目标名称
        /// </summary>
        public string TargetName { get; set; }

        /// <summary>
        /// 客户端ID
        /// </summary>
        public string ClientId { get; set; }

        /// <summary>
        /// Scope名称
        /// </summary>
        public string ScopeName { get; set; }

        /// <summary>
        /// 同步状态
        /// </summary>
        public ScopeSyncStatus SyncStatus { get; set; }

        /// <summary>
        /// 同步错误信息
        /// </summary>
        public string ErrorMessage { get; set; }

        /// <summary>
        /// 重试次数
        /// </summary>
        public int RetryCount { get; set; }

        /// <summary>
        /// 下次重试时间
        /// </summary>
        public DateTime? NextRetryTime { get; set; }

        public ScopeSyncStatusChangedEvent()
        {
        }

        public ScopeSyncStatusChangedEvent(
            ScopeSyncTargetType targetType,
            Guid targetId,
            string targetName,
            string clientId,
            string scopeName,
            ScopeSyncStatus syncStatus,
            string errorMessage = null)
        {
            TargetType = targetType;
            TargetId = targetId;
            TargetName = targetName;
            ClientId = clientId;
            ScopeName = scopeName;
            SyncStatus = syncStatus;
            ErrorMessage = errorMessage;
        }
    }

    /// <summary>
    /// 权限操作类型枚举
    /// </summary>
    public enum PermissionOperationType
    {
        /// <summary>
        /// 创建权限
        /// </summary>
        Created = 0,

        /// <summary>
        /// 更新权限
        /// </summary>
        Updated = 1,

        /// <summary>
        /// 删除权限
        /// </summary>
        Deleted = 2,

        /// <summary>
        /// 授予权限
        /// </summary>
        Granted = 3,

        /// <summary>
        /// 撤销权限
        /// </summary>
        Revoked = 4,

        /// <summary>
        /// 批量授权
        /// </summary>
        BatchGranted = 5,

        /// <summary>
        /// 批量撤销
        /// </summary>
        BatchRevoked = 6,

        /// <summary>
        /// 权限过期
        /// </summary>
        Expired = 7,

        /// <summary>
        /// 权限激活
        /// </summary>
        Activated = 8
    }

    /// <summary>
    /// Scope同步目标类型枚举
    /// </summary>
    public enum ScopeSyncTargetType
    {
        /// <summary>
        /// 用户
        /// </summary>
        User = 0,

        /// <summary>
        /// 角色
        /// </summary>
        Role = 1,

        /// <summary>
        /// 组
        /// </summary>
        Group = 2
    }

    /// <summary>
    /// Scope同步状态枚举
    /// </summary>
    public enum ScopeSyncStatus
    {
        /// <summary>
        /// 等待同步
        /// </summary>
        Pending = 0,

        /// <summary>
        /// 同步中
        /// </summary>
        Syncing = 1,

        /// <summary>
        /// 同步成功
        /// </summary>
        Succeeded = 2,

        /// <summary>
        /// 同步失败
        /// </summary>
        Failed = 3,

        /// <summary>
        /// 等待重试
        /// </summary>
        Retrying = 4,

        /// <summary>
        /// 已跳过
        /// </summary>
        Skipped = 5,

        /// <summary>
        /// 已取消
        /// </summary>
        Cancelled = 6
    }

    /// <summary>
    /// 权限变更项
    /// </summary>
    public class PermissionChangeItem
    {
        /// <summary>
        /// 权限名称
        /// </summary>
        public string PermissionName { get; set; }

        /// <summary>
        /// 权限显示名称
        /// </summary>
        public string DisplayName { get; set; }

        /// <summary>
        /// 权限模块
        /// </summary>
        public string Module { get; set; }

        /// <summary>
        /// 变更类型
        /// </summary>
        public PermissionChangeType ChangeType { get; set; }

        /// <summary>
        /// 权限值
        /// </summary>
        public bool Value { get; set; }

        /// <summary>
        /// 旧值
        /// </summary>
        public bool OldValue { get; set; }

        /// <summary>
        /// 生效时间
        /// </summary>
        public DateTime? EffectiveTime { get; set; }

        /// <summary>
        /// 过期时间
        /// </summary>
        public DateTime? ExpirationTime { get; set; }

        /// <summary>
        /// 变更原因
        /// </summary>
        public string Reason { get; set; }

        /// <summary>
        /// 额外属性
        /// </summary>
        public Dictionary<string, object> Properties { get; set; } = new();

        public PermissionChangeItem()
        {
        }

        public PermissionChangeItem(
            string permissionName,
            PermissionChangeType changeType,
            bool value = true,
            string reason = null)
        {
            PermissionName = permissionName;
            ChangeType = changeType;
            Value = value;
            Reason = reason;
        }
    }

    /// <summary>
    /// 权限变更类型枚举
    /// </summary>
    public enum PermissionChangeType
    {
        /// <summary>
        /// 授予权限
        /// </summary>
        Granted = 0,

        /// <summary>
        /// 撤销权限
        /// </summary>
        Revoked = 1,

        /// <summary>
        /// 更新权限
        /// </summary>
        Updated = 2,

        /// <summary>
        /// 权限过期
        /// </summary>
        Expired = 3,

        /// <summary>
        /// 权限激活
        /// </summary>
        Activated = 4
    }

    /// <summary>
    /// 权限定义
    /// </summary>
    public class PermissionDefinition
    {
        /// <summary>
        /// 权限名称
        /// </summary>
        public string Name { get; set; }

        /// <summary>
        /// 显示名称
        /// </summary>
        public string DisplayName { get; set; }

        /// <summary>
        /// 描述
        /// </summary>
        public string Description { get; set; }

        /// <summary>
        /// 权限组
        /// </summary>
        public string GroupName { get; set; }

        /// <summary>
        /// 权限模块
        /// </summary>
        public string Module { get; set; }

        /// <summary>
        /// 权限级别
        /// </summary>
        public int Level { get; set; }

        /// <summary>
        /// 是否启用
        /// </summary>
        public bool IsEnabled { get; set; }

        /// <summary>
        /// 是否为多租户权限
        /// </summary>
        public bool IsMultiTenant { get; set; }

        /// <summary>
        /// 权限属性
        /// </summary>
        public Dictionary<string, object> Properties { get; set; } = new();

        public PermissionDefinition()
        {
        }

        public PermissionDefinition(
            string name,
            string displayName,
            string module,
            int level = 0)
        {
            Name = name;
            DisplayName = displayName;
            Module = module;
            Level = level;
            IsEnabled = true;
        }
    }

    /// <summary>
    /// 权限变更上下文
    /// </summary>
    public class PermissionChangeContext
    {
        /// <summary>
        /// 请求ID
        /// </summary>
        public string RequestId { get; set; }

        /// <summary>
        /// 请求来源
        /// </summary>
        public string Source { get; set; }

        /// <summary>
        /// 客户端IP
        /// </summary>
        public string ClientIp { get; set; }

        /// <summary>
        /// 用户代理
        /// </summary>
        public string UserAgent { get; set; }

        /// <summary>
        /// 是否为批量操作
        /// </summary>
        public bool IsBatchOperation { get; set; }

        /// <summary>
        /// 批量操作ID
        /// </summary>
        public string BatchOperationId { get; set; }

        /// <summary>
        /// 事务ID
        /// </summary>
        public string TransactionId { get; set; }

        /// <summary>
        /// 上下文属性
        /// </summary>
        public Dictionary<string, object> Properties { get; set; } = new();

        /// <summary>
        /// 设置属性
        /// </summary>
        /// <param name="key">键</param>
        /// <param name="value">值</param>
        public void SetProperty(string key, object value)
        {
            Properties[key] = value;
        }

        /// <summary>
        /// 获取属性
        /// </summary>
        /// <typeparam name="T">值类型</typeparam>
        /// <param name="key">键</param>
        /// <param name="defaultValue">默认值</param>
        /// <returns>属性值</returns>
        public T GetProperty<T>(string key, T defaultValue = default)
        {
            if (Properties.TryGetValue(key, out var value) && value is T typedValue)
            {
                return typedValue;
            }
            return defaultValue;
        }
    }
}